package com.tang.juc.ThreadPool;

import java.util.concurrent.*;

/**
 * @author tlm
 * @version 1.0
 * @date 2020/4/28 15:15
 * 线程池的创建
 *
 */
public class ThreadPoolExample {
    public static void main(String[] args) {

        /*
        线程池的创建：
        《阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建，
        而是通过 ThreadPoolExecutor 的方式，这样的处理方式让写的同学更加
        明确线程池的运行规则，规避资源耗尽的风险
         */
        //方式一：通过构造方法实现:
        //ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor();
        //方式二：通过Executor 框架的工具类Executors来实现我们可以创建三种类型的ThreadPoolExecutor：


        // 1.FixedThreadPool ：该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个
        // 新的任务提交时，线程池中若有空闲线程，则立即执行。若没有，则新的任务会被暂存在一个任务队列中，
        // 待有线程空闲时，便处理在任务队列中的任务。
        //创建一个固定大小为15的线程池：
        ExecutorService executorService = Executors.newFixedThreadPool(15);

        // 2.SingleThreadExecutor： 方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池，任务
        // 会被保存在一个任务队列中，待线程空闲，按先入先出的顺序执行队列中的任务
        ExecutorService executorService1 = Executors.newSingleThreadExecutor();

        //CachedThreadPool： 该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定，但若
        // 有空闲线程可以复用，则会优先使用可复用的线程。若所有线程均在工作，又有新的任务提交，则会创建新的线
        // 程处理任务。所有线程在当前任务执行完毕后，将返回线程池进行复用。
        ExecutorService executorService2 = Executors.newCachedThreadPool();



        //线程池的七大参数:
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                //corePoolSize:核心线程数线程数定义了最小可以同时运行的线程数量。
                3,
                //maximumPoolSize:当队列中存放的任务达到队列容量的时候，当前可以同时运行的线程数量变为最大线程数。
                5,
                // keepAliveTime:当线程池中的线程数量大于 corePoolSize 的时候，如果这时没有新的任务提交，核心线程外
                // 的线程不会立即销毁，而是会等待，直到等待的时间超过了 keepAliveTime才会被回收销毁；
                3,
                //unit : keepAliveTime 参数的时间单位。
                TimeUnit.SECONDS,
                //workQueue: 当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数，如果达到的话，信任就会被存放在队列中。
                new LinkedBlockingDeque<>(3),
                //threadFactory :executor 创建新线程的时候会用到。
                Executors.defaultThreadFactory(),
                //handler :饱和策略(拒绝策略)。关于饱和策略下面单独介绍一下。
                new ThreadPoolExecutor.DiscardOldestPolicy());
        /*
        饱和策略(拒绝策略)：
         * new ThreadPoolExecutor.AbortPolicy() // 是默认的饱和策略，就是中止任务，该策略将抛出RejectedExecutionException。
         调用者可以捕获这个异常然后去编写代码处理异常。

         * new ThreadPoolExecutor.CallerRunsPolicy() // 是“调用者运行”策略，实现了一种调节机制 。它不会抛弃任务，
         也不会抛出异常。 而是将任务回退到调用者。它不会在线程池中执行任务，而是在一个调用了Executor的线程中执行该任务。

         * new ThreadPoolExecutor.DiscardPolicy() //队列满了，丢掉任务，不会抛出异常！

         * new ThreadPoolExecutor.DiscardOldestPolicy() //此策略将丢弃最早的未处理的任务请求（抛弃队列中最久的任务）。
         */

    }

}
